/// @tags: ACAutoMaton
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define rint register int

using std::cin;
using std::cout;

namespace BlueQuantum {

constexpr int maxn = 7.5e2 + 3, maxm = (maxn * maxn + maxn * 2) * 2, maxs = 1e7 + 5,
              inf = 0x3f3f3f3f;

int id[maxs], ch[maxs][2], fail[maxs], fa[maxs], end[maxn];
std::bitset<maxn> f[maxn];
std::string s[maxn];

inline void insert(const std::string &str, int i) {
  static int accnt = 0;
  int cur = 0;
  for (int c : str) {
    c -= 'a';
    if (!ch[cur][c]) ch[cur][c] = ++accnt;
    cur = ch[cur][c];
  }
  id[cur] = i, end[i] = cur;
}

inline void getFail(int x = 0) {
  std::queue<int> q;
  for (int i = 0; i < 2; ++i)
    if (ch[0][i]) q.push(ch[0][i]);
  while (!q.empty()) {
    x = q.front();
    q.pop();
    fa[x] = (id[x] ? x : fa[fail[x]]);
    for (int i = 0; i < 2; ++i) {
      int &v = ch[x][i];
      if (v) {
        fail[v] = ch[fail[x]][i];
        q.push(v);
      } else
        v = ch[fail[x]][i];
    }
  }
}

inline void search(const std::string &str, int x) {
  int len = str.length() - 1, cur = 0;
  for (int i = 0; i < len; ++i) {
    int c = str[i] - 'a';
    cur = ch[cur][c];
    f[x][id[fa[cur]]] = true;
  }
}

struct Edge {
  int v, nxt, f;
} e[maxm];

int ecnt = 1;
int heads[maxn * 2], cur[maxn * 2], dep[maxn * 2];

inline void add(int u, int v, int f = 1) {
  e[++ecnt].v = v, e[ecnt].nxt = heads[u], heads[u] = ecnt, e[ecnt].f = f;
  e[++ecnt].v = u, e[ecnt].nxt = heads[v], heads[v] = ecnt, e[ecnt].f = 0;
}

inline bool bfs(int s, int t) {
  std::queue<int> q;
  memset(dep, 0, sizeof(dep));
  memcpy(cur, heads, sizeof(cur));
  q.push(s);
  dep[s] = 1;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = heads[x]; i; i = e[i].nxt) {
      int v = e[i].v;
      if (e[i].f && dep[v] == 0) {
        dep[v] = dep[x] + 1;
        if (v == t) return true;
        q.push(v);
      }
    }
  }
  return false;
}

int dinic(int x, int t, int flow) {
  if (x == t) return flow;
  int rest = flow;
  for (int &i = cur[x]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (e[i].f && dep[v] == dep[x] + 1) {
      int k = dinic(v, t, std::min(e[i].f, rest));
      e[i].f -= k, e[i ^ 1].f += k;
      rest -= k;
      if (rest == 0) break;
    }
  }
  return flow - rest;
}

inline int main() {
  int n;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> s[i];
    insert(s[i], i);
  }
  getFail();
  for (int i = 1; i <= n; ++i) {
    f[i][id[fa[fail[end[i]]]]] = 1;
    search(s[i], i);
  }
  for (int i = 1; i <= n; ++i) f[i][i] = true;
  for (int k = 1; k <= n; ++k)
    for (int i = 1; i <= n; ++i)
      if (f[i][k] && i != k) f[i] |= f[k];
  int s = 0, t = n * 2 + 1;
  for (int i = 1; i <= n; ++i) add(s, i), add(i + n, t);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
      if (i != j && f[i][j]) {
        cout << i << ' ' << j << '\n';
        add(i, j + n, inf);
      }
  int ans = 0;
  while (bfs(s, t)) ans += dinic(s, t, inf);
  cout << n - ans;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("select.in", "r", stdin);
  freopen("select.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
